#include "config.h"
#include <sstream>
#include <unistd.h>
#include <sys/file.h>
#include <signal.h>
#include <csignal>
#include <json/json.h>
#include <fstream>
#include <iostream>
#include <string>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
const std::string LOCK_FILE = "/tmp/myapp.lock";
const std::string APP_CONFG = "./conf/app.conf";
app_config::app_config(std::shared_ptr<zlog_app> zlog_app) : _log(zlog_app)
{
    cout << "app_config constructor" << endl;
}

// 获取锁
bool app_config::acquire_lock(void)
{
    lock_fd = open(LOCK_FILE.c_str(), O_CREAT | O_RDWR, 0644);
    if (lock_fd == -1)
    {
        std::cerr << "Failed to open lock file: " << LOCK_FILE << std::endl;
        return false;
    }

    // 使用 flock 加独占锁（非阻塞）
    if (flock(lock_fd, LOCK_EX | LOCK_NB) == -1)
    {
        std::cerr << "Another instance is already running!\n";
        close(lock_fd);
        lock_fd = -1;
        return false;
    }

    // 清空文件并写入 PID
    lseek(lock_fd, 0, SEEK_SET);
    ftruncate(lock_fd, 0);
    std::ostringstream oss;
    oss << getpid();
    std::string pid_str = oss.str();
    write(lock_fd, pid_str.c_str(), pid_str.size());

    std::cout << "Acquired lock, PID=" << getpid() << std::endl;
    return true;
}

// 释放锁（会自动删除文件或解锁）
void app_config::release_lock(void)
{
    if (lock_fd != -1)
    {
        // 可选：清空文件内容
        ftruncate(lock_fd, 0);
        write(lock_fd, "terminated\n", 11);

        // 释放锁
        flock(lock_fd, LOCK_UN);
        close(lock_fd);
        lock_fd = -1;

        // 可选：删除锁文件
        unlink(LOCK_FILE.c_str());
    }
}

// config_example.cpp

// 将 dev_config 保存为 JSON 文件
bool app_config::save_config_to_file()
{
    const std::string filename = APP_CONFG;
    dev_config &config = cfg;
    Json::Value root;
    root["bind_port"] = config.bind_port;
    // root["dev_type"] = config.dev_type;
    // root["dev_ip"] = config.dev_ip;
    // root["rsp_num"] = config.rsp_num;
    root["modbus_udp_port"] = config.modbus_udp_port;
    root["modbus_ip"] = config.modbus_ip;
    root["auto_push_data"] = config.auto_push_data;
    root["auto_get_threshold"] = config.auto_get_threshold;
    root["eth_name"] = config.ethernet_card_name;
    root["dev_type_code"] = config.dev_type_code;
    root["modbus_tty"] = config.modbus_tty;
    // 写入文件
    std::ofstream ofs(filename);
    if (!ofs.is_open())
    {
        std::cerr << "Error: Cannot open file for writing: " << filename << std::endl;
        return false;
    }

    // 使用 StyledWriter 格式化输出
    Json::StreamWriterBuilder builder;
    builder["indentation"] = "  "; // 2 spaces
    std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
    writer->write(root, &ofs);
    ofs.close();

    std::cout << "Config saved to " << filename << std::endl;
    return true;
}

// 从 JSON 文件加载配置到 dev_config
bool app_config::load_config_from_file(void)
{
    const std::string filename = APP_CONFG;
    dev_config &config = cfg;
    std::ifstream ifs(filename);
    if (!ifs.is_open())
    {
        std::cerr << "Error: Cannot open file for reading: " << filename << std::endl;
        return false;
    }

    Json::Value root;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;

    // 解析 JSON
    if (!parseFromStream(readerBuilder, ifs, &root, &errs))
    {
        std::cerr << "Error: Failed to parse JSON: " << errs << std::endl;
        ifs.close();
        return false;
    }
    ifs.close();

    // 检查必要字段
    if (!root.isObject())
    {
        std::cerr << "Error: JSON is not an object." << std::endl;
        return false;
    }

    // 读取字段（注意类型检查）
    if (root.isMember("bind_port") && root["bind_port"].isUInt())
    {
        config.bind_port = static_cast<uint16_t>(root["bind_port"].asUInt());
    }
    else
    {
        cout << "bind_port is not found" << endl;
    }

    // if (root.isMember("dev_type") && root["dev_type"].isUInt())
    //     config.dev_type = static_cast<uint16_t>(root["dev_type"].asUInt());

    // if (root.isMember("dev_ip") && root["dev_ip"].isString())
    //     config.dev_ip = root["dev_ip"].asString();

    // if (root.isMember("rsp_num") && root["rsp_num"].isUInt())
    //     config.rsp_num = static_cast<uint16_t>(root["rsp_num"].asUInt());

    if (root.isMember("modbus_udp_port") && root["modbus_udp_port"].isUInt())
    {
        config.modbus_udp_port = static_cast<uint16_t>(root["modbus_udp_port"].asUInt());
    }
    else
    {
        cout << "modbus_udp_port is not found" << endl;
    }

    if (root.isMember("modbus_ip") && root["modbus_ip"].isString())
    {
        config.modbus_ip = root["modbus_ip"].asString();
    }
    else
    {
        cout << "modbus_ip is not found" << endl;
    }

    if (root.isMember("auto_push_data") && root["auto_push_data"].isUInt())
    {
        config.auto_push_data = static_cast<uint32_t>(root["auto_push_data"].asUInt());
    }
    else
    {
        cout << "auto_push_data is not found" << endl;
    }

    if (root.isMember("auto_get_threshold") && root["auto_get_threshold"].isUInt())
    {
        config.auto_get_threshold = static_cast<uint32_t>(root["auto_get_threshold"].asUInt());
    }
    else
    {
        cout << "auto_get_threshold is not found" << endl;
    }

    if (root.isMember("eth_name") && root["eth_name"].isString())
    {
        config.ethernet_card_name = root["eth_name"].asString();
    }
    else
    {
        cout << "eth_name is not found" << endl;
    }

    if (root.isMember("dev_type_code") && root["dev_type_code"].isUInt())
    {
        config.dev_type_code = static_cast<uint32_t>(root["dev_type_code"].asUInt());
    }
    else
    {
        cout << "dev_type_code is not found" << endl;
    }

    if (root.isMember("modbus_tty") && root["modbus_tty"].isString())
    {
        config.modbus_tty = root["modbus_tty"].asString();
    }
    else
    {
        cout << "modbus_tty is not found" << endl;
    }

    std::cout << "Config loaded from " << filename << std::endl;
    return true;
}

// 打印配置（用于测试）
void app_config::print_config(void)
{
    std::cout << " ===================== Device Config ===================== " << std::endl;
    std::cout << "Modbus UDP Port: " << cfg.modbus_udp_port << std::endl;
    std::cout << "Modbus IP: " << cfg.modbus_ip << std::endl;
    std::cout << "Auto Push Data: " << cfg.auto_push_data << std::endl;
    std::cout << "Auto Get Threshold: " << cfg.auto_get_threshold << std::endl;
    std::cout << "Ethernet Card Name: " << cfg.ethernet_card_name << std::endl;
    std::cout << "Device Type Code: " << cfg.dev_type_code << std::endl;
    std::cout << "Modbus TTY: " << cfg.modbus_tty << std::endl;
    std::cout << " ===================== Device Config ===================== " << std::endl;
}

/**
 * @brief 默认配置
 */
void app_config::default_config(void)
{
    cfg.bind_port = 1883;

    // cfg.dev_type = 1;
    // cfg.rsp_num = 5;
    // save_config_to_file(cfg);
}

/**
 * @brief 将格式为 "YYYY-MM-DD HH:MM:SS" 的字符串转换为时间戳
 *
 * @param str_time  输入的时间字符串
 * @param timestamp 输出的时间戳（通过指针返回）
 * @return int      转换成功返回 1，失败返回 0
 */
int app_config::datetime_to_timestamp(const char *str_time, time_t *timestamp)
{
    struct tm tm_time = {0};

    // 使用 strptime 解析时间字符串
    if (strptime(str_time, "%Y-%m-%d %H:%M:%S", &tm_time) == NULL)
    {

        return 1; // 解析失败
    }

    // 将 struct tm 转换为 time_t（UTC 时间戳）
    // 注意：strptime 解析的是本地时间，mktime 会按本地时区处理
    *timestamp = mktime(&tm_time);

    // 检查 mktime 是否出错
    if (*timestamp == -1)
    {
        return 1;
    }

    return 0; // 成功
}
/**
 * @brief 设置 Linux 系统时间
 *
 * @param timestamp 要设置的时间戳（UTC 时间）
 * @return int      成功返回 0，失败返回 1
 */
int app_config::set_linux_sys_time(time_t timestamp)
{
    struct timeval tv;
    tv.tv_sec = timestamp;
    tv.tv_usec = 0; // 不设置微秒
    // 设置系统时间
    if (settimeofday(&tv, NULL) == -1)
    {
        perror("settimeofday");
        fprintf(stderr, "Error: %s\n", strerror(errno));
        return 1;
    }
    return 0;
}
